package com.thinkgem.jeesite.modules.data.rep.web;

import com.thinkgem.jeesite.common.persistence.Page;
import com.thinkgem.jeesite.common.web.BaseController;
import com.thinkgem.jeesite.modules.data.rep.entity.*;
import com.thinkgem.jeesite.modules.data.rep.service.ReportConfService;
import com.thinkgem.jeesite.modules.sys.entity.Dict;
import com.thinkgem.jeesite.modules.sys.entity.Menu;
import com.thinkgem.jeesite.modules.sys.utils.DictUtils;
import com.thinkgem.jeesite.modules.sys.utils.UserUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by Havel on 2019/3/25/025.
 */
public abstract class ReportConfBaseController extends BaseController {

    protected TfEcReportConfig reportConfig;

    protected ReportConfigViewParams params;

    @Autowired
    ReportConfService reportConfService;


    protected  void common(HttpServletRequest request, Model model ){
        validateReport();
        processParametorIn(request);
        processParametorOut(model);
        model.addAttribute("report",reportConfig);
    }

    /**
     * 获取分页表格数据
     */
    protected void getReport(long reportId, HttpServletRequest request, HttpServletResponse response, Model model) {
        init(reportId);
        common(request,model);
        processDateTablePage(request, response, model);
    }


    /**
     * 获取图形化界面报表数据（堆积折线图）
     */
    protected void getReportForImg(long reportId, HttpServletRequest request, Model model) {
        init(reportId,null);
        common(request,model);
        processDateAllListForImg(model);
    }

    /**
     * 获取【分页数据】 和 【图形化报表】数据 == 注意页面参数处理
     */
    protected void getReportForTableAndImg(long reportId, HttpServletRequest request, HttpServletResponse response, Model model) {
        init(reportId,null);
        common(request,model);
        processDateTablePage(request, response, model);
        processDateAllListForImg(model);
    }

    /**
     * 初始化
     */
    protected void init() {
        reportConfig = new TfEcReportConfig();
    }

    protected void init(long reportId) {
        reportConfig = reportConfService.getConfigById(reportId);
    }

    protected void init(long reportId,ReportConfigViewParams params) {
        this.params = params;
        reportConfig = reportConfService.getConfigById(reportId);
        TfEcReportImgConf imgConfCond = new TfEcReportImgConf();
        imgConfCond.setReportId(reportId);
        imgConfCond.setIsShow(TfEcReportImgConf.TRUE);
        reportConfig.setReportImgConfs(reportConfService.findList(imgConfCond));
    }

    /**
     * 校验
     */
    protected void validateReport() {
        if (reportConfig == null) {
            throw new NullPointerException("没有此报表");
        }
        if (!secondGradePermissionVerify()) {
            throw new RuntimeException("没有访问报表数据的权限，请联系统管理员");
        }
    }

    /**
     * 二级权限校验：报表本身已经配置MenuCode，并且用户角色有这个权限
     * 如果报表没有MenuCode：则返回false（超级管理员除外）
     * 如果报表有menuCode，查看用户角色是否有这个菜单的权限，有则可以访问。
     */
    protected boolean secondGradePermissionVerify() {
        if (!StringUtils.isEmpty(reportConfig.getMenuCode())) {
            boolean flag = false;
            List<Menu> menuList = UserUtils.getMenuList();
            for (Menu m : menuList) {
                //if (reportConfig.getMenuCode().equals(m.getCode())) {
                //    flag = true;
                //    break;
                //}
            }
            return flag;
        }
        if (UserUtils.getUser().isAdmin()) {
            return true;
        }
        return false;
    }

    /**
     * 处理
     */
    public void processParametorIn(HttpServletRequest request) {
        TfEcReportConfigIn configIn = new TfEcReportConfigIn();
        configIn.setReportId(reportConfig.getReportId());
        List<TfEcReportConfigIn> reportIns = reportConfService.findList(configIn);
        reportConfig.setReportConfigIns(reportIns);
        List<Dict> selectList = null;
        if (reportIns != null && reportIns.size() != 0) {
            for (TfEcReportConfigIn reportIn : reportIns) {
                String param = request.getParameter(reportIn.getItemCode());
                if (StringUtils.isNotBlank(param)) {
                    if(TfEcReportConfigIn.THIRD_TYPE_MUTI.equals(reportIn.getThirdType())){
                        String[] params = request.getParameterValues(reportIn.getItemCode());
                        param = "";
                        for(int i = 0;i<params.length;i++){
                            param = (param +(params[i]+","));
                        }
                        param = param.substring(0,param.length()-1);
                    }
                    reportIn.setParamValue(param);
                } else {
                    if (StringUtils.isNotBlank(reportIn.getInitialValue())) {
                        reportIn.setParamValue(reportIn.getInitialValue());
                    }
                }

                String itemType = configIn.getItemType();
                if (TfEcReportConfigIn.ITEM_TYPE_MENU.equals(itemType)) {
                    if (StringUtils.isNotBlank(reportIn.getCheckType())) {
                        selectList = new ArrayList<Dict>();
                        String[] strs = reportIn.getCheckType().split(";");
                        for (int i = 0; i < strs.length; i++) {
                            Dict dict = new Dict();
                            String str[] = strs[i].split(",");
                            dict.setValue(str[0]);
                            dict.setLabel(str[1]);
                            selectList.add(dict);
                        }
                    }
                }else if(TfEcReportConfigIn.ITEM_TYPE_DICT.equals(itemType)) {
                    selectList = DictUtils.getDictList(reportIn.getCheckType());
                }else if(TfEcReportConfigIn.ITEM_TYPE_SQL.equals(itemType)){
                   selectList = reportConfService.findSelectList(reportIn.getCheckType());
                }
                reportIn.setSelectList(selectList);
            }
        }
    }

    /**
     * 处理出参
     */
    protected void processParametorOut(Model model) {
        //查询出参内容
        TfEcReportConfigOut configOut = new TfEcReportConfigOut();
        configOut.setReportId(reportConfig.getReportId());
        configOut.setSpanType(null);
        List<TfEcReportConfigOut> allOut = reportConfService.findList(configOut);

        //处理表头合并
        List<TfEcReportConfigOut> out0 = new ArrayList<>();
        List<TfEcReportConfigOut> out1 = new ArrayList<>();
        List<TfEcReportConfigOut> out2 = new ArrayList<>();
        List<TfEcReportConfigOut> out01 = new ArrayList<>();//需要映射的出参
        for (TfEcReportConfigOut out : allOut) {
            switch (out.getSpanType()) {
                case TfEcReportConfigOut.SPAN_TYPE_DEF:
                    out0.add(out);
                    out01.add(out);
                    break;
                case TfEcReportConfigOut.SPAN_TYPE_ROW:
                    out1.add(out);
                    out01.add(out);
                    break;
                case TfEcReportConfigOut.SPAN_TYPE_COL:
                    out2.add(out);
                    break;
            }
        }

        reportConfig.setReportConfigOuts(out01);

        model.addAttribute("out0", out0);
        model.addAttribute("out1", out1);
        model.addAttribute("out2", out2);
    }

    /**
     * 获取分页表单数据：此方法 必须放于 process*Img*()方法的前面
     */
    protected void processDateTablePage(HttpServletRequest request, HttpServletResponse response, Model model) {
        Page<TfEcReportConfig> page = reportConfig.getPage();
        page.setPageNo(getPageNo(request, response));
        page.setPageSize(getPageSize(request, response, 10));
        page = reportConfService.findResultListPage(page, reportConfig, "");
        model.addAttribute("page", page);
    }

    /**
     * 获取列表数据
     */
    protected void processDateAllListForImg(Model model) {
        List<TfEcReportImgConf> confs = reportConfig.getReportImgConfs();
        if (confs != null && confs.size() > 0) {
            for (TfEcReportImgConf conf : confs) {
                String sql = conf.getSqlRef();
                if (!StringUtils.isEmpty(sql)) {
                    reportConfig.setSqlRef(sql);
                    reportConfig.setPage(null);
                    List<Map<String, Object>> maps = reportConfService.findResultList(reportConfig, "");
                    //重构
                    switch (conf.getImgConfType()){
                        case TfEcReportImgConf.IMG_TYPE_Z_DUIJI:
                            EchartDataConvertUtils.convertEchartDataXDate(conf, maps, model);
                            break;
                        case TfEcReportImgConf.IMG_TYPE_Z_TWO_ITMES:
                            EchartDataConvertUtils.convertEchartTwoMonthCompare(conf, maps, model);
                            break;
                        case TfEcReportImgConf.IMG_TYPE_ZH_TIAO_STANDARD:
                            EchartDataConvertUtils.convertEchartDataTiao(conf, maps, model);
                            break;
                        case TfEcReportImgConf.IMG_TYPE_ZH_TIAO_STANDARD_1:
                            EchartDataConvertUtils.convertEchartDataTiao1(conf, maps, model);
                            break;
                    }
                    //PropertyFilter profilter = new PropertyFilter(){
                    //    @Override
                    //    public boolean apply(Object object, String name, Object value) {
                    //        if(name.equalsIgnoreCase("xAxisValues")||name.equalsIgnoreCase("yAxisValues")||name.equalsIgnoreCase("dataValues")){
                    //            //false表示last字段将被排除在外
                    //            return false;
                    //        }
                    //        return true;
                    //    }
                    //};
                    ////json使用自定义的拦截器
                    //Map<String,Object> map = new HashMap<>();
                    //map.put("xAxisValues",conf.getxAxisValues());
                    //map.put("yAxisValues",conf.getyAxisValues());
                    //map.put("dataValues",conf.getDataValues());
                    ////String json = JSON.toJSONString(TfEcReportImgConf.class, profilter);
                    //model.addAttribute("conf", URLEncoder.encode(JSONObject.toJSONString(map)));

                }
                //TODO 是否有扩展的必要
                else if (TfEcReportImgConf.TRUE.equals(conf.getIsMainData())) {
                    Page<Map<String, Object>> page = (Page<Map<String, Object>>) model.asMap().get("page");
                    if (page != null && page.getList() != null && page.getList().size() > 0) {
                        List<Map<String, Object>> maps = page.getList();
                        EchartDataConvertUtils.convertEchartDataXDate(conf, maps, model);
                    }
                }
                //else{
                //    throw new RuntimeException("配置数据异常，图形化SQL未配置["+conf.getImgConfId()+"]");
                //}
            }
        }
        //Date beginTime = request.getParameter("beginTime");
    }



    protected String cleanXssFilter(String value) {
        if (value != null) {
            value = value.replaceAll("& lt;", "<").replaceAll("& gt;", ">");
            value = value.replaceAll("& #40;", "\\(").replaceAll("& #41;", "\\)");
            value = value.replaceAll("& #39;", "'");
        }
        return value;
    }

}
